/**
 * @(#)Utility.java
 * (C)Copyright 2015 Toshiba Solutions Corporation, All rights reserved.
 */

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.FilenameFilter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

/**
 * @author TrinhNX This file does operation for file system
 * NOTE that these all operations are slower than native OS (of course)
 */
public final class FileUtility {
	private FileUtility() {
	}

	/**
	 * @param directory	: directory
	 * @param filter	: the filter name
	 * @param pattern	: array of matched pattern
	 * @return 			: List of matched file 
	 * 						empty list if not match
	 * @throws IOException file error or null file name
	 * * p/s: well well well TOCTOU
	 */
	public static List<File> filterFile(final File directory, final String filter, final String... pattern)
			throws IOException {
		List<File> matchedFile;
		if (directory == null)
			throw new IOException("Directory is null");
		if (!directory.isDirectory()) {
			throw new IOException("Directory path is not a directory");
		}
		// Default for 10 files
		matchedFile = new ArrayList<File>(10);
		// Filter it first then match the pattern :D to limit the execute time :3
		File[] filterFiles = directory.listFiles(new FileNameFilter(filter));
		if (filterFiles == null)
			throw new IOException("Check file sercurity");
		for (int i = 0; i < filterFiles.length; i++) {
			for (int j = 0; j < pattern.length; j++) {
				if (filterFiles[i].getName().contains(pattern[j])) {
					matchedFile.add(filterFiles[i]);
					break;
				}
			}
		}
		return matchedFile;
	}

	/**
	 * Get the list of file in the @directory that have the file format
	 * @prefix.@name.@extension
	 * @param directory
	 * @param prefix
	 * @param name
	 * @return List	: list file if ok
	 * @throws IOException
	 */
	public static List<File> getFiles(final File directory, final String prefix, final String extension,
			final String... name) throws IOException {
		// Initialize the list files
		List<File> files = new ArrayList<File>(name.length);
		for (int i = 0; i < name.length; i++) {
			File temp = getFile(directory, prefix + "." + name[i] + "." + extension);
			if (temp != null) {
				files.add(temp);
			}
		}
		return files;
	}

	/**
	 * Get the file_name inside the directory
	 * @param directory
	 * @param file_name
	 * @return File if file exist, null if not
	 */
	private static File getFile(final File directory, final String file_name) throws IOException {
		if (directory == null || !directory.isDirectory())
			throw new IOException("Path is empty or not directory");
		File file = new File(directory, file_name);
		// If file is existed and can be read, then return it else return null
		return (file.exists() && file.canRead()) ? file : null;
	}

	/**
	 * Here, zip it in temp folder on server then return to client.
	 * TODO: it is better to allow user select the location to save
	 * and then output directly into the client, server is no need save temp file 
	 */

	// This is used to filter the file inside directory
	// Do not mismatch with FileFilter
	private static class FileNameFilter implements FilenameFilter {
		private String filterName;

		public FileNameFilter(final String filterName) {
			this.filterName = filterName;
		}

		@Override
		public boolean accept(File file, String s) {
			return file.getName().contains(filterName);
		}
	}

	/**
	 * Read the file contain
	 * NOTE: FileReader does not support encoding char (wtf >"<)
	 * @author		: TrinhNX
	 * @param fileName
	 * @return
	 * @throws IOException
	 * @start_date	: 2015/05/20
	 * @end_date	:
	 */
	public static String readFile(final File fileName) throws IOException {
		StringBuilder sb = new StringBuilder(20);
		BufferedReader br = new BufferedReader(new FileReader(fileName));
		String line;
		while ((line = br.readLine()) != null) {
			sb.append(line);
		}
		return sb.toString();
	}
}